package com.gzx.plugin.tjzy.modular.fm.api;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import vip.xiaonuo.common.exception.CommonException;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Date;
import java.util.List;

/**
 * 发送闪信的接口
 *
 * @author 刘志刚
 */
@Slf4j
public class FmApi {

    // 短信批量发送接口
    private static final String SEND_MESSAGE_API_PATH = "/api/sendMessage";

    // 查询余额接口
    private static final String GET_BALANCE_API_PATH = "/api/getBalance";

    /**
     * 闪信批量发送接口
     *
     * @param phoneList 手机号码
     * @param content   短信内容
     */
    public static void sendMessage(String userName, String password, String baseUri, List<String> phoneList, String content) {
        String url = buildApiUrl(baseUri, SEND_MESSAGE_API_PATH);
        // 时间戳
        long timestamp = new Date().getTime();
        // 拼接JSON
        JSONObject jsons = buildBaseJson(userName,content, password, timestamp);
        jsons.put("content", content);
        jsons.put("phoneList", phoneList);
        // 发送请求
        postRequest(url, jsons);
    }

    /**
     * 查询余额接口
     *
     * @param userName 账号
     * @param password 密码
     * @param baseUri  地址
     */
    public static void getBalance(String userName, String password, String baseUri) {
        String url = buildApiUrl(baseUri, GET_BALANCE_API_PATH);
        // 时间戳
        long timestamp = new Date().getTime();
        JSONObject jsons = buildBaseJson(userName,"", password, timestamp);
        postRequest(url, jsons);
    }

    /**
     * 向指定地址发一个post请求，带着data数据
     *
     * @param jsonObject。 请求体
     * @param url         请求地址
     * @throws ParseException 解析异常
     * @throws IOException    IO异常
     */
    public static void postRequest(String url, JSONObject jsonObject) {
        long startTime = System.currentTimeMillis();
        log.info("调用闪信API [{}], 请求参数: {}", url, jsonObject);
        String encoding = "utf-8";
        //创建httpclient对象
        CloseableHttpClient client = HttpClients.createDefault();
        //创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);
        //装填参数
        StringEntity s = new StringEntity(jsonObject.toString(), encoding);
        s.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
        //设置参数到请求对象中
        httpPost.setEntity(s);
        httpPost.setHeader("Content-type", "application/json");
        httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        try {
            //执行请求操作，并拿到结果（同步阻塞）
            CloseableHttpResponse response = client.execute(httpPost);
            //获取结果实体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                //按指定编码转换结果实体为String类型
                String resbody = EntityUtils.toString(entity, encoding);
                log.info("调用闪信API [{}] 响应结果: {}, 耗时: {}ms", url, resbody, System.currentTimeMillis() - startTime);
            }
            //释放链接
            EntityUtils.consume(entity);
            response.close();
        } catch (Exception e) {
            log.error("调用闪信API [{}] 异常:{}", url, e);
        }
    }

    private static String buildApiUrl(String baseUri, String path) {
        return baseUri.endsWith("/") ? baseUri + path.substring(1) : baseUri + path;
    }

    private static JSONObject buildBaseJson(String userName,String content , String password, long timestamp) {
        String passwordMd5 = md5(password);
        String signContent = userName + content + timestamp + passwordMd5;
        String sign = md5(signContent);

        JSONObject json = new JSONObject();
        json.put("userName", userName);
        json.put("timestamp", timestamp);
        json.put("sign", sign);
        return json;
    }

    /**
     * md5加密(Byte)
     *
     * @param text。需要加密的内容
     * @return 加密后的结果
     */
    private static String md5(String text) {
        if (text == null || "".equals(text.trim())) {
            log.error("MD5加密内容不可为空");
            return null;
        }
        try {
            MessageDigest m = MessageDigest.getInstance("md5");
            m.update(text.getBytes(StandardCharsets.UTF_8));
            byte[] arr = m.digest();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < arr.length; ++i) {
                String hex = Integer.toHexString(arr[i] & 0xFF);
                if (hex.length() < 2) {
                    sb.append('0');
                }
                sb.append(hex);
            }
            return sb.toString();
        } catch (Exception e) {
            log.error("闪信内容的MD5加密失败", e);
        }
        return null;
    }
}
